package com.xiaoq.hotel.endpoint;

import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.coms.util.MathUtil;
import com.xiaoq.feature.entity.ShopFoodEntity;
import com.xiaoq.feature.vo.ShopFoodVo;
import com.xiaoq.hotel.Vo.HotelListVo;
import com.xiaoq.hotel.Vo.HotelVo;
import com.xiaoq.hotel.entity.HotelEntity;
import com.xiaoq.hotel.service.IHotelService;
import com.xiaoq.parking.entity.ParkingEntity;
import com.xiaoq.parking.vo.ParkingVo;
import com.xiaoq.sites.entity.SitesEntity;
import com.xiaoq.sites.service.ISitesService;
import com.xiaoq.sites.vo.SitesDetailVo;
import com.xiaoq.vo.PagingVo;
import io.swagger.annotations.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Api(tags={"酒店接口"})
@RestController
@RequestMapping("/api/v1/hotel")
public class HotelEndpoint {

    @Autowired
    private IHotelService hotelSer;

    @Autowired
    private IdGenerator idGenerator;


    @Autowired
    private ISitesService sitesService;

    public class HotelDataResponse extends GenericListResponse<HotelVo> {}

    public class HotelDResponse extends GenericDataResponse<HotelVo> {}

    public class HotelListResponse extends GenericDataResponse<HotelListVo> {}

    @ApiOperation(value = "添加酒店", notes = "添加酒店")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "添加酒店") })
    @PostMapping(value = "/hotel", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> addHotel(
            @RequestBody @ApiParam(value = "hotelVo", required = true) HotelVo hotelVo, HttpServletRequest request) {

        HotelEntity hotel = new HotelEntity();
        BeanUtils.copyProperties(hotelVo, hotel);
        hotel.setId(idGenerator.nextId());
        hotelSer.saveHotel(hotel);
        return GenericResponse.ok();

    }


    @ApiOperation(value = "修改酒店", notes = "修改酒店")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "修改酒店") })
    @PutMapping(value = "/hotel", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> updateHotel(
            @RequestBody @ApiParam(value = "hotelVo", required = true) HotelVo hotelVo, HttpServletRequest request) {

        HotelEntity hotel = new HotelEntity();
        BeanUtils.copyProperties(hotelVo, hotel);
        hotelSer.saveHotel(hotel);
        return GenericResponse.ok();

    }

    @ApiOperation(value = "删除酒店", notes = "删除酒店")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "删除酒店") })
    @DeleteMapping(value = "/hotel", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> deleteHotel(
            @RequestParam(value = "id") @ApiParam(value = "hotelVo", required = true) String id, HttpServletRequest request) {

        hotelSer.delete(id);
        return GenericResponse.ok();

    }

    @ApiOperation(value = "删除酒店(批量)", notes = "删除酒店(批量)")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "删除酒店(批量)") })
    @DeleteMapping(value = "/hotels", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> deleteHotels(
            @RequestParam(value = "ids") @ApiParam(value = "ids", required = true) List<String> ids, HttpServletRequest request) {
        for(String id:ids){
            hotelSer.delete(id);
        }
        return GenericResponse.ok();

    }

    @ApiOperation(value = "下架(批量)", notes = "下架(批量)")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "下架(批量)") })
    @DeleteMapping(value = "/delss", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> delHotels(
            @RequestParam(value = "ids") @ApiParam(value = "ids", required = true) List<String> ids,
            @RequestParam(value = "delTag") @ApiParam(value = "10 上架，00下架", required = true) String delTag,
            HttpServletRequest request) {
        for(String id:ids){
            HotelEntity hotel = hotelSer.findHotelDetail(id);
            hotel.setDelTag(delTag);
            hotelSer.saveHotel(hotel);
        }
        return GenericResponse.ok();

    }


    @ApiOperation(value = "修改序号", notes = "修改序号")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "修改序号") })
    @PutMapping(value = "/delss", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> updateSort(
            @RequestParam(value = "id") @ApiParam(value = "id", required = true) String id,
            @RequestParam(value = "sort") @ApiParam(value = "序号", required = true) Integer sort,
            HttpServletRequest request) {

        HotelEntity hotel = hotelSer.findHotelDetail(id);
        hotel.setSort(sort);
        hotelSer.saveHotel(hotel);
        return GenericResponse.ok();

    }

    @ApiOperation(value = "酒店列表", notes = "酒店列表")
    @ApiResponses({ @ApiResponse(code = 200, response = HotelListResponse.class, message = "酒店列表") })
    @GetMapping(value = "/hotels", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> findHotels(
            @RequestParam(value = "cityCode") @ApiParam(value = "城市编码") String cityCode,
            @RequestParam(value="localLongitude",required=false)@ApiParam(value="当前经度",required=false)Double localLongitude,
            @RequestParam(value="localLatitude",required=false)@ApiParam(value="当前纬度",required=false)Double localLatitude,
            HttpServletRequest request) {

        List<HotelEntity> hotels = hotelSer.findHotel(cityCode);
        List<HotelVo> hotelList = new ArrayList<>();
        HotelVo hotelVo = null;
        for(HotelEntity hotel:hotels){
            hotelVo = new HotelVo();
            BeanUtils.copyProperties(hotel,hotelVo);
            if (localLongitude != null && localLatitude != null && localLongitude != 0.00 && localLatitude != 0.00) {
                Double shopLongitude = hotelVo.getLongitude();
                Double shopLatitude = hotelVo.getLatitude();
                Double distance = MathUtil.distance(localLongitude, localLatitude, shopLongitude, shopLatitude);
                hotelVo.setDistance(distance);
                String distanceString = MathUtil.distance(distance);
                hotelVo.setDistanceString(distanceString);
            }
            hotelList.add(hotelVo);
        }

        List<SitesEntity> sitesEntityList = sitesService.findSitesListbyZoneCity(cityCode,null);
        List<SitesDetailVo> sitesDetailVos = new ArrayList<>();
        SitesDetailVo sitesDetailVo = null;
        for(SitesEntity sites:sitesEntityList){
            sitesDetailVo = new SitesDetailVo();
            sitesDetailVo.setId(sites.getId());
            sitesDetailVo.setName(sites.getName());
            sitesDetailVos.add(sitesDetailVo);
        }

        List<HotelEntity> rhotels = hotelSer.findHotel(cityCode,"1");
        List<HotelVo> rhotelList = new ArrayList<>();
        HotelVo rhotelVo = null;
        for(HotelEntity hotel:rhotels){
            rhotelVo = new HotelVo();
            BeanUtils.copyProperties(hotel,rhotelVo);
            rhotelList.add(rhotelVo);
        }
        HotelListVo hotelListVos = new HotelListVo();
        hotelListVos.setHotelVos(hotelList);
        hotelListVos.setSites(sitesDetailVos);
        hotelListVos.setrHotelVos(rhotelList);

        return HotelListResponse.okWithData(hotelListVos);

    }

    @ApiOperation(value = "酒店列表(gov)", notes = "酒店列表(gov)")
    @ApiResponses({ @ApiResponse(code = 200, response = HotelDataResponse.class, message = "酒店列表(gov)") })
    @GetMapping(value = "/hotels/gov", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> findHotels(
            @RequestParam(value = "cityCode") @ApiParam(value = "城市编码") String cityCode,
            @RequestParam(value = "delTag",required = false) @ApiParam(value = "城市编码",required = false) String delTag,
            @ModelAttribute(value = "pvo") PagingVo pvo,
            HttpServletRequest request) {

        List<HotelEntity> hotels = hotelSer.findHotel(cityCode,delTag,pvo);
        List<HotelVo> hotelList = new ArrayList<>();
        HotelVo hotelVo = null;
        for(HotelEntity hotel:hotels){
            hotelVo = new HotelVo();
            BeanUtils.copyProperties(hotel,hotelVo);

            hotelList.add(hotelVo);
        }

        return HotelDataResponse.listAndCount(hotelList, (Long) pvo.getTc());

    }

    @ApiOperation(value = "推荐酒店列表", notes = "推荐酒店列表")
    @ApiResponses({ @ApiResponse(code = 200, response = HotelDataResponse.class, message = "推荐酒店列表") })
    @GetMapping(value = "/recommend", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> recommend(
            @RequestParam(value = "cityCode") @ApiParam(value = "城市编码") String cityCode,
            @RequestParam(value="localLongitude",required=false)@ApiParam(value="当前经度",required=false)Double localLongitude,
            @RequestParam(value="localLatitude",required=false)@ApiParam(value="当前纬度",required=false)Double localLatitude,
            HttpServletRequest request) {
        List<HotelEntity> rhotels = hotelSer.findHotel(cityCode,"1");
        List<HotelVo> rhotelList = new ArrayList<>();
        HotelVo rhotelVo = null;
        for(HotelEntity hotel:rhotels){
            rhotelVo = new HotelVo();
            BeanUtils.copyProperties(hotel,rhotelVo);
            Double shopLongitude = hotel.getLongitude();
            Double shopLatitude = hotel.getLatitude();
            Double distance = MathUtil.distance(localLongitude, localLatitude, shopLongitude, shopLatitude);
            rhotelVo.setDistance(distance);
            String distanceString = MathUtil.distance(distance);
            rhotelVo.setDistanceString(distanceString);
            rhotelList.add(rhotelVo);
        }

        return HotelDataResponse.listNoCount(rhotelList);

    }

    @ApiOperation(value = "推荐酒店详情", notes = "推荐酒店详情")
    @ApiResponses({ @ApiResponse(code = 200, response = HotelDResponse.class, message = "推荐酒店详情") })
    @GetMapping(value = "/detail", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> detail(
            @RequestParam(value = "id") @ApiParam(value = "酒店编码") String id,
            @RequestParam(value="localLongitude",required=false)@ApiParam(value="当前经度",required=false)Double localLongitude,
            @RequestParam(value="localLatitude",required=false)@ApiParam(value="当前纬度",required=false)Double localLatitude,
            HttpServletRequest request) {
        HotelEntity hotel = hotelSer.findHotelDetail(id);

        HotelVo hotelVo =  new HotelVo();
        BeanUtils.copyProperties(hotel,hotelVo);

        if (localLongitude != null && localLatitude != null && localLongitude != 0.00 && localLatitude != 0.00) {
            Double shopLongitude = hotelVo.getLongitude();
            Double shopLatitude = hotelVo.getLatitude();
            Double distance = MathUtil.distance(localLongitude, localLatitude, shopLongitude, shopLatitude);
            hotelVo.setDistance(distance);
            String distanceString = MathUtil.distance(distance);
            hotelVo.setDistanceString(distanceString);
        }



        return HotelDResponse.okWithData(hotelVo);

    }

    @ApiOperation(value = "获取景区附近的酒店", notes = "获取景区附近的酒店")
    @ApiResponses({ @ApiResponse(code = 200, response = HotelDataResponse.class, message = "获取景区附近的酒店") })
    @GetMapping(value="/feature", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> findShopFoodList(
            @RequestParam(value="sitesId",required=false)@ApiParam(value="景区Id",required=false)String sitesId,
            @RequestParam(value="localLongitude",required=false)@ApiParam(value="当前经度",required=false)Double localLongitude,
            @RequestParam(value="localLatitude",required=false)@ApiParam(value="当前纬度",required=false)Double localLatitude,
            @ModelAttribute(value="pvo") PagingVo pvo) {

        SitesEntity sites = sitesService.findById(sitesId);
        Double longitude = sites.getCenterLongitude();
        Double latitude = sites.getCenterLatitude();

        List<HotelEntity> hotels = hotelSer.findShopFoodList(longitude, latitude, localLongitude, localLatitude, pvo);
        List<HotelVo> hotelVoList = new ArrayList<>();
        HotelVo hotelVo = null;
        for (HotelEntity hotel : hotels) {
            hotelVo = new HotelVo();
            BeanUtils.copyProperties(hotel, hotelVo);
            if (localLongitude != null && localLatitude != null && localLongitude != 0.00 && localLatitude != 0.00) {
                Double shopLongitude = hotelVo.getLongitude();
                Double shopLatitude = hotelVo.getLatitude();
                Double distance = MathUtil.distance(localLongitude, localLatitude, shopLongitude, shopLatitude);
                hotelVo.setDistance(distance);
                String distanceString = MathUtil.distance(distance);
                hotelVo.setDistanceString(distanceString);
            }
            hotelVoList.add(hotelVo);
        }
        if (hotelVoList != null && hotelVoList.size() > 1) {

            Collections.sort(hotelVoList, new Comparator<HotelVo>() {

                @Override
                public int compare(HotelVo hotelVo1, HotelVo shopFoodVo2) {

                    Double status2 = hotelVo1.getDistance() - shopFoodVo2.getDistance();
                    if (status2 > 0.0) {
                        return 1;
                    } else {
                        return -1;
                    }

                }
            });
        }
        Long total = (Long) pvo.getTc();
        List<HotelVo> hotelVoList2 = new ArrayList<>();
        int pn = (pvo.getPn() - 1) * pvo.getPs();
        int ps = pn + pvo.getPs();
        if (pvo.getPn() >= 1 && pn < total) {
            if (ps > total) {
                ps = total.intValue();
            }
            for (int i = pn; i < ps; i++) {
                hotelVoList2.add(hotelVoList.get(i));
            }
        }

        return HotelDataResponse.listAndCount(hotelVoList2, total);
    }
}
